package com.xnck.ifpms.dao;

import java.lang.reflect.ParameterizedType;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.nutz.dao.Cnd;
import org.nutz.dao.Condition;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Entity;
import org.nutz.dao.pager.Pager;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.sql.SqlCallback;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 数据处理基类
 * @author zhangmengliang
 *
 * @param <T>
 */
public class BaseDao<T> {

	protected Class<T> persistentClass;
	
	@Autowired
	protected Dao dao;

	public Dao getDao() {
		return dao;
	}

	public void setDao(Dao dao) {
		this.dao = dao;
	}
	
	@SuppressWarnings("unchecked")  
	public BaseDao()
	{  
	    // 获取持久化对象的类型  
	    this.persistentClass = (Class<T>) ((ParameterizedType) getClass()  
	            .getGenericSuperclass()).getActualTypeArguments()[0];  
	}
	
	/**
	 * 按主键查询
	 * @param id String主键
	 * @return
	 * @throws
	 * @author:zhangmengliang
	 * @date: 2015年8月9日
	 */
	public T get(String id){
		return dao.fetch(this.persistentClass, id);
	}
	
	/**
	 * 按主键查询
	 * @param id Int主键
	 * @return
	 * @throws
	 * @author:zhangmengliang
	 * @date: 2015年8月9日
	 */
	public T get(Integer id){
		return dao.fetch(this.persistentClass, id);
	}
	
	/**
	 * 查询所有
	 * @return
	 * @throws
	 * @author:zhangmengliang
	 * @date: 2015年8月9日
	 */
	public List<T> search(){
		return dao.query(this.persistentClass, null);
	}
	
	/**
	 * 分页查询所有
	 * @param currentPage 当前页
	 * @param pageSize 每页数量
	 * @return
	 * @throws
	 * @author:zhangmengliang
	 * @date: 2015年8月9日
	 */
	public List<T> search(int currentPage,int pageSize){
		Pager pager = dao.createPager(currentPage, pageSize);
		return dao.query(this.persistentClass, null, pager);
	}
	
	/**
	 * 查询所有
	 * @param orderBy 排序字段名称(asc)
	 * @return
	 * @throws
	 * @author:zhangmengliang
	 * @date: 2015年8月9日
	 */
	public List<T> search(String orderBy){
		return dao.query(this.persistentClass, Cnd.orderBy().asc(orderBy), null);
	}
	
	/**
	 * 分页查询所有
	 * @param orderBy 排序字段名称(asc)
	 * @param currentPage
	 * @param pageSize
	 * @return
	 * @throws
	 * @author:zhangmengliang
	 * @date: 2015年8月9日
	 */
	public List<T> search(String orderBy, int currentPage,int pageSize){
		Pager pager = dao.createPager(currentPage, pageSize);
		return dao.query(this.persistentClass, Cnd.orderBy().asc(orderBy), pager);
	}
	
	/**
	 * 按条件查询
	 * @param condition 输入的条件
	 * @return
	 * @throws
	 * @author:zhangmengliang
	 * @date: 2015年8月9日
	 */
	public List<T> search(Condition condition){
		return dao.query(this.persistentClass, condition, null);
	}
	
	/**
	 * 按条件分页查询
	 * @param condition 条件
	 * @param currentPage 当前页
	 * @param pageSize 每页数量
	 * @return
	 * @throws
	 * @author:zhangmengliang
	 * @date: 2015年8月9日
	 */
	public List<T> searchByPage(Condition condition, int currentPage,int pageSize){
		Pager pager = dao.createPager(currentPage, pageSize);
		return dao.query(this.persistentClass, condition, pager);
	}
	
	/**
	 * 获取所有数据总数
	 * @return
	 * @throws
	 * @author:zhangmengliang
	 * @date: 2015年8月9日
	 */
	public int searchCount(){
		return dao.count(this.persistentClass);
	}
	
	/**
	 * 按条件获取所有数据总数
	 * @param condition 条件
	 * @return
	 * @throws
	 * @author:zhangmengliang
	 * @date: 2015年8月9日
	 */
	public int searchCount(Condition condition){
		return dao.count(this.persistentClass, condition);
	}
	
	/**
	 * 按条件查询总数
	 * @param sqlName sql名称
	 * @param condition 条件
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年10月14日
	 */
	public int searchCount(String sqlName, Condition condition){
		Sql sql = dao.sqls().create(sqlName);
	    sql.setCondition(condition);
	    return this.searchCount(sql);
	}
	
	/**
	 * 按条件查询总数
	 * @param sql sql对象
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年10月15日
	 */
	public int searchCount(Sql sql){
		sql.setCallback(new SqlCallback() {
			@Override
			public Object invoke(Connection conn, ResultSet rs, Sql sql) throws SQLException {
				int count = -1;
	            if(rs.next()){
	            	count = rs.getInt(1);
	            }
	            return count;
			}
	    });
	    dao.execute(sql);
	    return sql.getInt();
	}
	
	/**
	 * 按条件分页查询
	 * @param sqlName sql名称
	 * @param condition 条件
	 * @param currentPage 当前页
	 * @param pageSize 每页数量
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年10月14日
	 */
	public List<T> search(String sqlName, Condition condition){
		Sql sql = dao.sqls().create(sqlName);
	    sql.setCondition(condition);
	    return this.search(sql);
	}
	
	/**
	 * 按条件分页查询
	 * @param sqlName sql名称
	 * @param condition 条件
	 * @param currentPage 当前页
	 * @param pageSize 每页数量
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年10月14日
	 */
	public List<T> searchByPage(String sqlName, Condition condition, int currentPage,int pageSize){
		Sql sql = dao.sqls().create(sqlName);
	    sql.setCondition(condition);
	    return this.searchByPage(sql, currentPage, pageSize);
	}
	
	/**
	 * 按条件分页查询
	 * @param sql sql对象
	 * @param currentPage 当前页
	 * @param pageSize 每页数量
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年10月15日
	 */
	public List<T> search(Sql sql){
		sql.setCallback(Sqls.callback.entities());
	    Entity<T> entity = dao.getEntity(this.persistentClass);
	    sql.setEntity(entity);
	    dao.execute(sql);
	    return sql.getList(this.persistentClass);
	}
	
	/**
	 * 按条件分页查询
	 * @param sql sql对象
	 * @param currentPage 当前页
	 * @param pageSize 每页数量
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年10月15日
	 */
	public List<T> searchByPage(Sql sql, int currentPage,int pageSize){
		Pager pager = dao.createPager(currentPage, pageSize);
		sql.setCallback(Sqls.callback.entities());
	    sql.setPager(pager);
	    Entity<T> entity = dao.getEntity(this.persistentClass);
	    sql.setEntity(entity);
	    dao.execute(sql);
	    return sql.getList(this.persistentClass);
	}
	
	/**
	 * 获取指定的关联对象
	 * @param t 查询的对象
	 * @param fieldName 查询对象内需要获取的对象
	 * @throws
	 * @author:zhangmengliang
	 * @date: 2015年8月9日
	 */
	public void findLink(T t, String fieldName){
		dao.fetchLinks(t, fieldName);
	}
	
	/**
	 * 按条件获取指定的关联对象
	 * @param t 查询的对象
	 * @param fieldName 查询对象内需要获取的对象
	 * @param condition 条件
	 * @author:zhangmengliang
	 * @date: 2015年10月14日
	 */
	public void findLink(T t, String fieldName, Condition condition){
		dao.fetchLinks(t, fieldName, condition);
	}
	
	/**
	 * 插入一条新数据
	 * @param t 新数据
	 * @return
	 * @throws
	 * @author:zhangmengliang
	 * @date: 2015年8月9日
	 */
	public T insert(T t){
		return dao.insert(t);
	}
	
	/**
	 * 关联数据信息
	 * @param t 对象
	 * @param fieldName 被关联的属性
	 * @author:zhangmengliang
	 * @date: 2015年10月16日
	 */
	public T insertRelation(T t, String fieldName){
		return dao.insertRelation(t, fieldName);
	}
	
	/**
	 * 更新
	 * @param t 跟新的对象
	 * @return true:更新成功;false:更新失败
	 * @throws
	 * @author:zhangmengliang
	 * @date: 2015年8月9日
	 */
	public boolean update(T t){
		return dao.updateIgnoreNull(t) == 1;
	}
	
	/**
	 * 按主键删除数据(如果主键标识为@Name)
	 * @param id
	 * @return
	 * @throws
	 * @author:zhangmengliang
	 * @date: 2015年8月9日
	 */
	public boolean delete(String id){
		return dao.delete(this.persistentClass, id) > 0;
	}
	
	/**
	 * 按主键删除数据(如果主键标识为@Id)
	 * @param id
	 * @return
	 * @throws
	 * @author:zhangmengliang
	 * @date: 2015年8月9日
	 */
	public boolean delete(Integer id){
		return dao.delete(this.persistentClass, id) > 0;
	}
	
	/**
	 * 将对象删除的同时，也将符合一个正则表达式的所有关联字段关联的对象统统删除
	 * @param t 数据对象
	 * @param fildName 正则表达式
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年11月5日
	 */
	public int deleteWith(T t, String fildName){
		return dao.deleteWith(t, fildName);
	}
	
	/**
	 * 按条件清除数据
	 * @param condition
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年9月23日
	 */
	public int clear(Condition condition){
		return dao.clear(this.persistentClass, condition);
	}
	
	/**
	 * 清除关联关系
	 * @param t 对象
	 * @param fieldName 关联的属性
	 * @return
	 * @author:zhangmengliang
	 * @date: 2015年10月17日
	 */
	public T clearLinks(T t, String fieldName){
		return dao.clearLinks(t, fieldName);
	}
}
